home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 1 / PC Actual CD 01.iso / f1 / prt.arj / PRTSCR.ASM next >
Encoding:
Assembly Source File  |  1992-07-22  |  18.5 KB  |  463 lines

  1.                 name    PrtScr
  2.                 title   PrintScreen Impresión de pantalla selectiva
  3.                 subttl  CopyRight (c) 1992 by Aitor Garay
  4.  
  5. ScreenLenght    equ     (80d*25d*2d)
  6.  
  7. code            segment
  8.                 assume  cs:code,ds:code,es:code,ss:code
  9.                 org     100h            ; por ser de tipo COM
  10. Init:           jmp     Start
  11.  
  12. PrtScrVector    proc    near            ; rutina general de control
  13.                 cmp     cs:State,1d     ; comprobar si ya esta en memoria
  14.                 jnz     StartCode
  15.                 iret                    ; ignorar segundas llamadas
  16. StartCode:      mov     cs:State,1d     ; activar bandera
  17.                 cld                     ; para proceso de cadenas
  18.                 push    ax              ; salvar registros alterados
  19.                 push    bx
  20.                 push    cx
  21.                 push    dx
  22.                 push    si
  23.                 push    di
  24.                 push    es
  25.                 push    ds
  26.                 mov     ax,cs           ; inicializar registros de segmento
  27.                 mov     ds,ax
  28.                 mov     es,ax
  29.                 mov     ah,0fh          ; obtener modo de video vía BIOS
  30.                 int     10h
  31.                 cmp     al,02h          ; comprobar modos procesables
  32.                 jz      VideoOk
  33.                 cmp     al,03h
  34.                 jz      VideoOk
  35.                 cmp     al,07h
  36.                 jz      VideoOk
  37.                 mov     ax,0e07h        ; emitir pitido como señal de aviso
  38.                 int     10h
  39. CallLast:       pushf                   ; simular una int 05h al vector anterior
  40.                 call    dword ptr LastVector
  41. EndCode:        pop     ds
  42.                 pop     es
  43.                 pop     di
  44.                 pop     si
  45.                 pop     dx
  46.                 pop     cx
  47.                 pop     bx
  48.                 pop     ax
  49.                 mov     cs:State,0d
  50.                 iret                    ; volver al codigo original
  51. VideoOk:        mov     ax,ScreenSeg    ; actualizar valor del segmento de pantalla activo
  52.                 mov     ScreenFSeg,ax
  53.                 mov     ax,4096d        ; calcular el OFFSET del la página activa
  54.                 mov     cl,8d
  55.                 shr     bx,cl
  56.                 mul     bx
  57.                 add     ScreenFSeg,ax
  58.                 call    ScreenSave      ; salvar contenido de la pantalla
  59.                 call    MakeWindow      ; dibujar el recuadro
  60. WaitUser:       xor     ah,ah
  61.                 int     16h             ; esperar a alguna tecla
  62.                 cmp     ax,1c0dh        ; ¿ RETURN ?
  63.                 jnz     NextKey00
  64.                 inc     xCoord          ; ajustar coordenadas
  65.                 inc     yCoord
  66.                 dec     x1Coord
  67.                 dec     y1Coord
  68.                 call    PrintCode       ; llamar a codigo de impresión
  69.                 inc     y1Coord
  70.                 inc     x1Coord
  71.                 dec     yCoord
  72.                 dec     xCoord
  73.                 call    ScreenRestore   ; recuperar pantalla
  74.                 jmp     EndCode         ; salir
  75.  
  76. NextKey00:      cmp     ax,3920h        ; ¿ ESPACE ?
  77.                 jnz     NextKey01
  78.                 call    PrintCode
  79.                 call    ScreenRestore
  80.                 jmp     EndCode
  81.  
  82. NextKey01:      cmp     ax,0e08h        ; ¿ BACKSPACE ?
  83.                 jnz     NextKey02
  84.                 call    ScreenRestore
  85.                 jmp     CallLast
  86.  
  87. NextKey02:      cmp     ax,011bh        ; ¿ ESCAPE ?
  88.                 jnz     TestShift
  89.                 call    ScreenRestore
  90.                 jmp     EndCode
  91.  
  92. TestShift:      push    ax              ; guardar tecla obtenida
  93.                 mov     ah,02h
  94.                 int     16h             ; obtener marcas del teclado
  95.                 and     al,00000011b    ; comprobar marcas SHIFT
  96.                 pop     ax
  97.                 jnz     ShiftKey
  98.                 jmp     NormalKey
  99.  
  100. ShiftKey:       cmp     ax,4800h        ; ¿ SHIFT-UP ?
  101.                 jnz     NextKey03
  102.                 mov     al,y1Coord      ; comprobar rango
  103.                 dec     al              ; ajustar rango
  104.                 cmp     al,yCoord
  105.                 jnz     ShiftUpOk
  106.                 jmp     WaitUser        ; operación invalida
  107. ShiftUpOk:      dec     y1Coord
  108.                 jmp     RedrawScreen    ; regenerar la pantalla
  109.  
  110. NextKey03:      cmp     ax,5000h        ; ¿ SHIFT-DOWN ?
  111.                 jnz     NextKey04
  112.                 cmp     y1Coord,24d
  113.                 jnz     ShiftDownOk
  114.                 jmp     WaitUser
  115. ShiftDownOk:    inc     y1Coord
  116.                 jmp     RedrawScreen
  117.  
  118. NextKey04:      cmp     ax,4b00h        ; ¿ SHIFT-LEFT ?
  119.                 jnz     NextKey05
  120.                 mov     al,x1Coord
  121.                 dec     al
  122.                 cmp     al,xCoord
  123.                 jnz     ShiftLeftOk
  124.                 jmp     WaitUser
  125. ShiftLeftOk:    dec     x1Coord
  126.                 jmp     RedrawScreen
  127.  
  128. NextKey05:      cmp     ax,4d00h        ; ¿ SHIFT-RIGHT ?
  129.                 jnz     UndefShiftKey
  130.                 cmp     x1Coord,79d
  131.                 jnz     ShiftRightOk
  132. UndefShiftKey:  jmp     WaitUser        ; volver a leer tecla
  133. ShiftRightOk:   inc     x1Coord
  134.                 jmp     RedrawScreen
  135.  
  136. NormalKey:      cmp     ax,4800h        ; ¿ UP ?
  137.                 jnz     NextKey06
  138.                 cmp     yCoord,0d       ; comprobar rango
  139.                 jnz     UpOk
  140.                 mov     ax,4800h        ; simula un SHIFT-UP
  141.                 jmp     ShiftKey        ; saltar para reproceso
  142. UpOk:           dec     yCoord
  143.                 dec     y1Coord
  144.                 jmp     RedrawScreen
  145.  
  146. NextKey06:      cmp     ax,5000h        ; ¿ DOWN ?
  147.                 jnz     NextKey07
  148.                 cmp     y1Coord,24d
  149.                 jnz     DownOk
  150.                 cmp     Recursive,1d    ; comprobar modo recursivo
  151.                 jnz     NextDown
  152.                 mov     Recursive,0d
  153.                 jmp     WaitUser
  154. NextDown:       mov     ah,05h
  155.                 mov     cx,5000h        ; simula un DOWN
  156.                 int     16h
  157.                 mov     ax,4800h        ; simula un SHIFT-UP
  158.                 mov     Recursive,1d    ; activar modo recursivo
  159.                 jmp     ShiftKey
  160. DownOk:         inc     yCoord
  161.                 inc     y1Coord
  162.                 mov     Recursive,0d    ; desactivar modo recursivo
  163.                 jmp     RedrawScreen
  164.  
  165. NextKey07:      cmp     ax,4b00h        ; ¿ LEFT ?
  166.                 jnz     NextKey08
  167.                 cmp     xCoord,0d
  168.                 jnz     LeftOk
  169.                 mov     ax,4b00h        ; simula un SHITF-LEFT
  170.                 jmp     ShiftKey
  171. LeftOk:         dec     xCoord
  172.                 dec     x1Coord
  173.                 jmp     RedrawScreen
  174.  
  175. NextKey08:      cmp     ax,4d00h        ; ¿ RIGHT ?
  176.                 jnz     NextKey09
  177.                 cmp     x1Coord,79d
  178.                 jnz     RightOk
  179.                 cmp     Recursive,1d    ; comprobar si estoy en modo recursivo
  180.                 jnz     NextRight
  181.                 mov     Recursive,0d    ; ya no lo estoy
  182.                 jmp     WaitUser        ; esperar siguiente tecla
  183. NextRight:      mov     ah,05h
  184.                 mov     cx,4d00h        ; simula un RIGHT
  185.                 int     16h
  186.                 mov     ax,4b00h        ; simula un SHIFT-LEFT
  187.                 mov     Recursive,1d    ; activar modo recursivo
  188.                 jmp     ShiftKey
  189. RightOk:        inc     xCoord
  190.                 inc     x1Coord
  191.                 mov     Recursive,0d    ; desactivar modo recursivo
  192.                 jmp     RedrawScreen
  193.  
  194. NextKey09:      cmp     ax,4838h        ; ¿ 8 ?
  195.                 jnz     NextKey10
  196.                 mov     ax,4800h        ; simula un SHIFT-UP
  197.                 jmp     ShiftKey
  198.  
  199. NextKey10:      cmp     ax,4d36h        ; ¿ 6 ?
  200.                 jnz     NextKey11
  201.                 mov     ax,4d00h        ; simula un SHIFT-RIGHT
  202.                 jmp     ShiftKey
  203.  
  204. NextKey11:      cmp     ax,4b34h        ; ¿ 4 ?
  205.                 jnz     NextKey12
  206.                 mov     ax,4b00h        ; simula un SHIFT-LEFT
  207.                 jmp     ShiftKey
  208.  
  209. NextKey12:      cmp     ax,5032h        ; ¿ 2 ?
  210.                 jnz     UndefKey
  211.                 mov     ax,5000h        ; simula un SHIFT-DOWN
  212.                 jmp     ShiftKey
  213.  
  214. UndefKey:       jmp     WaitUser
  215.  
  216. RedrawScreen:   call    ScreenRestore
  217.                 call    MakeWindow
  218.                 jmp     WaitUser
  219. PrtScrVector    endp
  220.  
  221. GotoXY          proc    near            ; mueve DI a coordenadas X,Y (ah,al)
  222.                 mov     di,ax           ; la formula utilizada es :
  223.                 mov     bl,160d         ; OFFSET = Y*160 + X*2
  224.                 mul     bl
  225.                 xchg    di,ax
  226.                 mov     cl,8d
  227.                 shr     ax,cl
  228.                 shl     ax,1d
  229.                 add     di,ax
  230.                 ret
  231. GotoXY          endp
  232.  
  233. MakeWindow      proc    near
  234.                 push    es
  235.                 mov     es,ScreenFSeg   ; semgneto de pantalla definitivo
  236.                 xor     cx,cx           ; para ahorrar codigo mas tarde
  237.                 mov     ah,xCoord       ; coordenadas ininicales
  238.                 mov     al,yCoord
  239.                 call    GotoXY
  240.                 mov     ax,00FDAh       ; caracter '┌'
  241.                 stosw
  242.                 call    DrawLine        ; dibujar linea horizontal
  243.                 mov     ax,00FBFh       ; caracter '┐'
  244.                 stosw
  245.                 mov     cl,y1Coord      ; calcular longitud de la linea vertical
  246.                 sub     cl,yCoord
  247.                 dec     cl
  248.                 jz      NoVertLine      ; no hay linea vectical
  249.                 mov     dh,xCoord       ; para ahorrar tiempo
  250.                 mov     dl,x1Coord
  251.                 mov     bh,yCoord
  252. DrawNext:       push    cx              ; salvar contador general del bucle
  253.                 mov     ah,dh
  254.                 mov     al,bh
  255.                 add     al,cl           ; dibuja de abajo para arriba
  256.                 push    ax              ; para ser utilizado mas tarde
  257.                 call    GotoXY
  258.                 mov     ax,00FB3h       ; caracter '│'
  259.                 stosw
  260.                 pop     ax
  261.                 mov     ah,dl
  262.                 call    GotoXY
  263.                 mov     ax,00FB3h       ; caracter '│'
  264.                 stosw
  265.                 pop     cx
  266.                 loop    DrawNext
  267. NoVertLine:     mov     ah,xCoord
  268.                 mov     al,y1Coord
  269.                 call    GotoXY
  270.                 mov     ax,00FC0h       ; caracter '└'
  271.                 stosw
  272.                 call    DrawLine
  273.                 mov     ax,00FD9h       ; caracter '┘'
  274.                 stosw
  275.                 pop     es              ; antes de salir recuperar ES
  276.                 ret
  277. DrawLine        label   near            ; no merece crean una rutina aparte
  278.                 mov     cl,x1Coord      ; calcular tamaño en horizontal
  279.                 sub     cl,xCoord
  280.                 dec     cl              ; ajustarlo
  281.                 mov     ax,00FC4h       ; caracter '─'
  282.                 rep     stosw
  283.                 ret
  284. MakeWindow      endp
  285.  
  286. ScreenSave      proc    near            ; salva el contenido de la pantalla
  287.                 push    ds
  288.                 mov     ds,ScreenFSeg
  289.                 xor     si,si
  290.                 mov     di,offset ScreenBuffer
  291.                 mov     cx,ScreenLenght/2
  292.                 rep     movsw
  293.                 pop     ds
  294.                 ret
  295. ScreenSave      endp
  296.  
  297. ScreenRestore   proc    near            ; recupera la pantalla del buffer
  298.                 push    es
  299.                 mov     es,ScreenFSeg
  300.                 xor     di,di
  301.                 mov     si,offset ScreenBuffer
  302.                 mov     cx,ScreenLenght/2
  303.                 rep     movsw
  304.                 pop     es
  305.                 ret
  306. ScreenRestore   endp
  307.  
  308. PrintCode       proc    near            ; rutina de impresión
  309.                 push    es
  310.                 mov     es,ScreenFSeg
  311.                 xor     ch,ch           ; parte alta de CX siempre a cero
  312.                 mov     cl,x1Coord      ; calcular numero de columnas
  313.                 sub     cl,xCoord
  314.                 inc     cl
  315.                 mov     NumColum,cl     ; guardar numero de columnas
  316.                 mov     cl,y1Coord      ; calcular numero de lineas
  317.                 sub     cl,yCoord
  318.                 cmp     cl,0d           ; comprobar numero de lineas nulo
  319.                 jl      PrintExit
  320.                 inc     cl              ; CL = numero de lineas a imprimir
  321.                 mov     al,yCoord       ; inicializar linea actual
  322.                 mov     CurrentLine,al
  323. NextLine:       push    cx
  324.                 mov     ah,xCoord
  325.                 mov     al,CurrentLine
  326.                 call    GotoXY
  327.                 mov     si,offset ScreenBuffer
  328.                 add     si,di
  329.                 mov     cl,NumColum
  330.                 or      cl,cl           ; comprobar numero de columnas nulo
  331.                 jz      Continue
  332.  
  333. NextCaracter:   lodsb                   ; cargar caracter
  334.                 inc     si              ; ignorar el atributo
  335.                 cmp     al,20h          ; comprobar caracteres de control
  336.                 jae     CaracterOk
  337.                 mov     al,20h          ; filtrar caracteres de control
  338. CaracterOk:     mov     byte ptr es:[di],al     ; dibujar rastro de impresión
  339.                 inc     di
  340.                 mov     byte ptr es:[di],78h
  341.                 inc     di
  342.                 xor     ah,ah           ; enviar caracter a impresora
  343.                 xor     dx,dx
  344.                 int     17h
  345.                 loop    NextCaracter    ; procesar siguiente caracter
  346.  
  347. Continue:       mov     ax,000dh        ; imprimir el par CR-LF
  348.                 xor     dx,dx
  349.                 int     17h
  350.                 mov     ax,000ah
  351.                 xor     dx,dx
  352.                 int     17h
  353.                 inc     CurrentLine     ; actualizar linea actual
  354.                 pop     cx
  355.                 loop    NextLine        ; siguiente linea por favor ...
  356.  
  357. PrintExit:      pop     es
  358.                 ret
  359. PrintCode       endp
  360.  
  361. ScreenSeg       dw      0B800h          ; segmento inicial del segmento  de pantalla
  362. ScreenFSeg      dw      0B800h          ; segmento final del buffer de pantalla
  363. State           db      0               ; ¿ estoy ya en pantalla ?
  364. Recursive       db      0               ; ¿ estoy en modo recursivo ?
  365. xCoord          db      26d             ; coordenadas de la ventana
  366. yCoord          db      8d
  367. x1Coord         db      52d
  368. y1Coord         db      16d
  369. LastVector      dd      0               ; vector 05h anterior
  370. NumColum        db      0               ; numero de columnas a imprimir
  371. CurrentLine     db      0               ; linea de impresión actual
  372. ScreenBuffer    db      0               ; el buffer se crea 'al vuelo'
  373.  
  374. Start           proc    near            ; el atributo NEAR es irrelevante
  375.                 cld
  376.                 mov     ax,Title0L      ; visualizar titulos
  377.                 mov     si,offset Title0
  378.                 call    ScreenCenter
  379.                 mov     ax,Title1L
  380.                 mov     si,offset Title1
  381.                 call    ScreenCenter
  382.                 call    ScreenCR
  383.                 push    ds
  384.                 xor     ax,ax           ; AX=0000h
  385.                 mov     ds,ax
  386.                 lds     si,ds:[0014h]   ; [DS:SI] vector de interrupción 05h
  387.                 mov     di,offset PrtScrVector
  388.                 mov     cx,0ah          ; 10 palabras iguales es mucha casualidad
  389.                 repz    cmpsw
  390.                 jz      AlreadyInst
  391.                 mov     ds,ax           ; AX=0000h
  392.                 mov     si,0014h        ; salvar vector 05h anterior
  393.                 mov     di,offset LastVector
  394.                 movsw
  395.                 movsw
  396.                 pop     ds
  397.                 push    es
  398.                 mov     es,ax           ; AX todavía es 0000h
  399.                 mov     di,0014h
  400.                 mov     ax,offset PrtScrVector
  401.                 stosw                   ; colocar OFFSET
  402.                 mov     ax,cs
  403.                 stosw                   ; colocar SEGMENT
  404.                 pop     es
  405.                 int     11h             ; obtener configuración del sistema
  406.                 and     ax,0030h        ; aislar campo -> tipo de video
  407.                 cmp     ax,0030h        ; comprobar si es adaptador mono
  408.                 jnz     ColorAdapted
  409.                 mov     ScreenSeg,0B000h        ; segmento para adaptador mono
  410. ColorAdapted:   mov     si,offset InstallTxt
  411.                 call    ScreenPrint
  412.                 call    ScreenCR
  413.                 mov     dx,offset ScreenBuffer+ScreenLenght
  414.                 int     27h             ; DOS TSR
  415. AlreadyInst:    pop     ds              ; recuperar DS
  416.                 mov     si,offset NoInstallTxt
  417.                 call    ScreenPrint     ; visualizar texto de no instalar
  418.                 call    ScreenCR
  419.                 int     20h             ; pasar el control al DOS
  420. Start           endp
  421.  
  422. ScreenPrint     proc    near            ; visualiza texto hasta encontrar NULL
  423.                 lodsb
  424.                 or      al,al
  425.                 jz      EndPrint
  426.                 mov     ah,0eh
  427.                 xor     bx,bx
  428.                 int     10h             ; BIOS TTY
  429.                 jmp     ScreenPrint
  430. EndPrint:       ret
  431. ScreenPrint     endp
  432.  
  433. ScreenCenter    proc    near            ; visualiza texto centrado
  434.                 mov     cx,ax
  435. CenterPad:      mov     ax,0e20h
  436.                 xor     bx,bx
  437.                 int     10h
  438.                 loop    CenterPad
  439.                 call    ScreenPrint
  440.                 call    ScreenCR
  441.                 ret
  442. ScreenCenter    endp
  443.  
  444. ScreenCR        proc    near            ; visualiza el par CR-LF
  445.                 mov     ax,0e0dh
  446.                 xor     bx,bx
  447.                 int     10h
  448.                 mov     ax,0e0ah
  449.                 xor     bx,bx
  450.                 int     10h
  451.                 ret
  452. ScreenCR        endp
  453.  
  454. Title0          db      'Print Screen V1.0  Impresión selectiva de pantalla',0d
  455. Title0L         equ     (80-($-Title0-1))/2
  456. Title1          db      'por Aitor Garay',0d
  457. Title1L         equ     (80-($-Title1-1))/2
  458. InstallTxt      db      'Print Screen acaba de ser instalado.',0d
  459. NoInstallTxt    db      'Print Screen ya ha sido instalado anteriormente.',0d
  460.  
  461. code            ends
  462. end             Init
  463.